/**
 * SchemaForm - 类型定义
 * 该文件根据 `prd.md` 生成，所有字段均含中文注释。
 */

import type {
  ControllerRenderProps,
  FieldValues,
  Path,
  RegisterOptions,
} from "react-hook-form";
import type { InputProps } from "../ui/input";
import type { FunctionComponent } from "react";

export type RenderFieldComponent<
  TFormValues extends FieldValues = FieldValues,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
> = ControllerRenderProps<TFormValues, Path<TFormValues>> & any;

type InputFieldConfig<T extends FieldValues = FieldValues> =
  BasicFieldConfig<T> & {
    component: "Input";
    props?: Omit<InputProps, "value" | "onChange">;
  };

export type CustomFieldConfig<T extends FieldValues = FieldValues> =
  BasicFieldConfig<T> & {
    component?: "Custom";
    props?: Record<string, unknown>;
    render: FunctionComponent<RenderFieldComponent<T>>;
  };

export type IFieldConfig<T extends FieldValues = FieldValues> =
  | InputFieldConfig<T>
  | CustomFieldConfig<T>;

export type IFieldConfigComponent = Exclude<
  NonNullable<IFieldConfig["component"]>,
  "Custom"
>;

// 字段类型定义
interface BasicFieldConfig<
  TFieldValues extends FieldValues = FieldValues,
  TName extends Path<TFieldValues> = Path<TFieldValues>,
> {
  /** 字段名（键）：在 form 中的唯一标识，必填 */
  name: TName & string;
  /** 标签：UI 显示的文本标签 */
  label?: string;
  /** 描述信息：用于提供字段的额外说明 */
  description?: string;
  /** 默认值：字段初始化时的默认值 */
  default?: unknown;
  /** 校验规则：与 UI 层 FormField 的 rules 形状一致，支持数组或对象形式 */
  rules?: Omit<
    RegisterOptions<TFieldValues, TName>,
    "valueAsNumber" | "valueAsDate" | "setValueAs" | "disabled"
  >;
  required?: boolean;
  /** 可见性：布尔、声明式条件或回调（支持基于其它字段的联动） */
  visible?:
    | boolean
    | {
        dependsOn: Path<TFieldValues>[];
        handler: (formValues: TFieldValues) => boolean;
      };
  /** 禁用：布尔、声明式条件或回调（支持基于其它字段的联动） */
  disabled?:
    | boolean
    | {
        dependsOn: Path<TFieldValues>[];
        handler: (formValues: TFieldValues) => boolean;
      };
  // onChangeEffects?: (value: unknown, form: UseFormReturn<TFieldValues>) => void;
  className?: string;
}
